//
// Created by XMac on 16/6/20.
// Copyright (c) 2016 XBN. All rights reserved.
//

#import "XBNTimeLimitCountDownCalculator.h"


@interface XBNTimeLimitCountDownCalculator ()

@property(nonatomic , strong)dispatch_source_t timer;

@property(nonatomic , strong) NSMutableArray *processBlocks;

@property(nonatomic , strong) NSMutableArray *cancelBlocks;

@end

@implementation XBNTimeLimitCountDownCalculator

- (instancetype)init
{
    self = [super init];
    if (self) {
        _processBlocks = [@[] mutableCopy];
        
        _cancelBlocks = [@[] mutableCopy];
        
        [self addObserver:self forKeyPath:@"remainTimeInterval" options:NSKeyValueObservingOptionNew context:nil];
    }
    return self;
}


-(void)addProcessBlock:(TimeLimitProcessBlock)xProcessBlock cancelBlock:(TimeLimitCancelBlock)xCancelBlock {
    
    //持有了传过来的block 注意循环引用问题
    [_processBlocks addObject:xProcessBlock];
    
    [_cancelBlocks addObject:xCancelBlock];
}

-(void)timeLimitCountDownResume{
    @synchronized (self) {
        if (_timer) {
            return;
        }
        
        __weak __typeof(self) weakself = self;
        _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
        dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0);
        dispatch_source_set_event_handler(_timer, ^{
            __strong __typeof(self) strongSelf = weakself;
            if (strongSelf.remainTimeInterval == 0) {
                dispatch_source_cancel(strongSelf.timer);
            }else{
                strongSelf.remainTimeInterval --;
            }
        });
        dispatch_source_set_cancel_handler(_timer, ^{
            __strong __typeof(self) strongSelf = weakself;
            [strongSelf.cancelBlocks enumerateObjectsUsingBlock:^(TimeLimitCancelBlock  _Nonnull cancelBlock, NSUInteger idx, BOOL * _Nonnull stop) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    cancelBlock();
                });
            }];
        });
        dispatch_resume(_timer);
    }
}

-(void)timeLimitCountDownClear{
    
    [_processBlocks removeAllObjects];
    
    [_cancelBlocks removeAllObjects];
    
    if (_timer) {
        dispatch_source_cancel(_timer);
    }
    _timer = nil;
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"remainTimeInterval"] && object == self) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            [_processBlocks enumerateObjectsUsingBlock:^(TimeLimitProcessBlock  _Nonnull processBlock, NSUInteger idx, BOOL * _Nonnull stop) {
                processBlock(self.remainTimeInterval);
            }];
        });
    }
}

-(void)dealloc{
    [_processBlocks removeAllObjects];
    
    [_cancelBlocks removeAllObjects];
    
    [self removeObserver:self forKeyPath:@"remainTimeInterval"];
}




@end
